package com.atguigu.yygh.common.utils;

import com.atguigu.yygh.common.exception.YyghException;
import com.atguigu.yygh.common.result.ResultCode;
import io.jsonwebtoken.*;
import org.apache.commons.lang3.StringUtils;

import java.nio.charset.StandardCharsets;
import java.util.Date;

public class JwtHelper {

    static String subject = "YYGH-USER";
    static String key = "atguigu123";
    static long time = 1000 * 60 * 60 * 24; //1天


    /**
     * 生成jwt
     * @param userId 用户id，会作为jwt的载荷存入
     * @param userName 用户名，会作为jwt的载荷存入
     * @return 得到令牌
     */
    public static String createToken(Long userId, String userName) {

        JwtBuilder builder = Jwts.builder(); //生成器对象
        String jwt = builder
                //头
                .setHeaderParam("alg", "HS256")
                .setHeaderParam("typ", "JWT")
                //载荷（默认）
                .setSubject(subject)
                .setExpiration(new Date(System.currentTimeMillis() + time))
                //载荷（私有）
                .claim("userId", userId)
                .claim("userName", userName)
                //签名hash
                .signWith(SignatureAlgorithm.HS256, key.getBytes(StandardCharsets.UTF_8))
                //连起来
                .compact();

        return jwt;
    }

    /**
     * 解析jwt并获取载荷
     * @param token
     * @return 得到jwt载荷（令牌中存储的数据）
     */
    public static Claims parseToken(String token) {

        if(StringUtils.isEmpty(token)){
            throw new YyghException(ResultCode.ERROR, "需要登录");
        }

        JwtParser parser = Jwts.parser().setSigningKey(key.getBytes(StandardCharsets.UTF_8));//解析器
        Jws<Claims> claimsJws = null;
        try {
            claimsJws = parser.parseClaimsJws(token);
        } catch (Exception e) {
            throw new YyghException(ResultCode.ERROR, "需要登录", e);
        }
        Claims body = claimsJws.getBody();
        return body;
    }

    /**
     * 通过token解析出userId
     * @param token
     * @return
     */
    public static Long getUserId(String token) {

        Claims claims = parseToken(token);
        Object userIdObj = claims.get("userId");
        Long userId = null;
        if(userIdObj instanceof Integer){
            userId = ((Integer)userIdObj).longValue();
            System.out.println("userId = " + userId);
        }else{
            userId = (Long)userIdObj;
            System.out.println("userId = " + userId);
        }

        return userId;
    }

    /**
     * 通过token解析userName
     * @param token
     * @return
     */
    public static String getUserName(String token) {

        Claims claims = parseToken(token);
        String userName = (String)claims.get("userName");
        return userName;
    }

    public static void main(String[] args) {

        String token = createToken(1L, "tom");
        System.out.println(token);

        Claims claims = parseToken(token);
        Object userIdObj = claims.get("userId");
        if(userIdObj instanceof Integer){
            Integer userId = (Integer)userIdObj;
            System.out.println("userId = " + userId);
        }else{
            Long userId = (Long)userIdObj;
            System.out.println("userId = " + userId);
        }
        String userName = (String)claims.get("userName");


        System.out.println("userName = " + userName);
    }
}
